package cn.edu.zzuli.wechat.login.service.impl;

import cn.edu.zzuli.common.exception.CustomException;
import cn.edu.zzuli.common.result.Result;
import cn.edu.zzuli.common.result.ResultInfo;
import cn.edu.zzuli.model.entity.Identity;
import cn.edu.zzuli.model.entity.User;
import cn.edu.zzuli.model.vo.wx.WXAuth;
import cn.edu.zzuli.wechat.login.mapper.IdentityMapper;
import cn.edu.zzuli.wechat.login.mapper.UserLoginMapper;
import cn.edu.zzuli.wechat.login.service.UserLoginService;
import cn.edu.zzuli.common.utils.JWTUtils;
import cn.edu.zzuli.common.utils.MailUtil;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.mail.EmailException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;


@Service
@Slf4j
public class UserLoginServiceImpl extends ServiceImpl<UserLoginMapper,User> implements UserLoginService {
    @Value("${wxmini.appid}")
    public String appid;
    @Value("${wxmini.secret}")
    private String secret;

    @Autowired
    private WxService wxService;

    @Autowired
    private UserLoginMapper userLoginMapper;

    @Autowired
    private IdentityMapper identityMapper;

    /**
     * 登录方法
     * @param wxAuth
     * @return
     */
    @Override
    public ResultInfo getSessionId(WXAuth wxAuth) {
        String url = "https://api.weixin.qq.com/sns/jscode2session?appid={0}&secret={1}&js_code={2}&grant_type=authorization_code";
        String replaceUrl = url.replace("{0}", appid).replace("{1}", secret).replace("{2}", wxAuth.getCode());
        String res = HttpUtil.get(replaceUrl);
        JSONObject jsonObject = JSON.parseObject(res);
        String sessionKey = (String) jsonObject.get("session_key");
        String openId = (String) jsonObject.get("openid");
        return this.authLogin(wxAuth,sessionKey,openId);
    }

    /**
     * 查询身份方法
     * @param identity
     */
    @Override
    //@Cacheable(value = "identity",key ="'identities'")
    public void checkIdentity(Identity identity) {
        //查询身份
        Identity ide = this.check(identity);
        if(ide == null){
            throw new CustomException("认证失败!");
        }
        //更新用户认证状态
        baseMapper.updateById(new User(identity.getIuid(),1));

        //邮箱通知
        try {
            MailUtil.sendEmail(identity.getName(),identity.getEmail());
        } catch (EmailException e) {
            e.printStackTrace();
        }
    }



    //查询身份
    private Identity check(Identity identity) {
        QueryWrapper wrapper = new QueryWrapper();
        if (identity.getName() != null) {
            wrapper.eq("name",identity.getName());
        }
        if(identity.getCollege() != null){
            wrapper.eq("college",identity.getCollege());
        }
        if(identity.getStuId() != null){
            wrapper.eq("stu_id",identity.getStuId());
        }

        Identity ide = identityMapper.selectOne(wrapper);
        return ide;
    }

    //登录操作
    private ResultInfo authLogin(WXAuth wxAuth,String sessionKey,String openId){

        try {
            String json = wxService.wxDecrypt(wxAuth.getEncryptedData(), sessionKey, wxAuth.getIv());
            log.info(json);
            User wxuser = JSON.parseObject(json, User.class);
            log.info("wxuser: {}",wxuser);
            wxuser.setOpenId(openId);
            User user = userLoginMapper.selectOne(new QueryWrapper<User>().eq("open_id",openId));
            log.info("user: {}",user);
            if(user == null){
                //注册
                log.info("----{}-----","注册");
                return this.register(wxuser);
            }else {
                //登录
                log.info("----{}-----","登录");
                return this.login(user);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return Result.fail("登录失败");
    }

    //登录
    private ResultInfo login(User user) {
        Map<String,String> map = new HashMap<>();
        Integer uid = user.getUid();
        String token = JWTUtils.sign(uid);
        map.put("token",token);
        return Result.ok(map);
    }

    //注册
    private ResultInfo register(User user) {
        int res = userLoginMapper.insert(user);
        return this.login(user);
    }
}
